package com.loong.android.tools;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 编码工具类，实现url、unicode及任意文本的编码和解码
 */
public class Encode {

    /**
     * url编码
     * @param content 编码内容
     * @param encoding 编码，如utf-8、gbk等
     */
    public static String URLEncode(String content, String encoding) {
        try {
            return URLEncoder.encode(content, encoding);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 以utf-8格式对url编码
     * @param content 编码内容
     */
    public static String URLEncode(String content) {
        return URLEncode(content, "utf-8");
    }

    /**
     * url解码
     * @param content 解码内容
     * @param encoding 编码，如utf-8、gbk等
     */
    public static String URLDecode(String content, String encoding) {
        try {
            return URLDecoder.decode(content, encoding);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 以utf-8格式对url解码
     * @param content 编码内容
     */
    public static String URLDecode(String content) {
        return URLDecode(content, "utf-8");
    }

    /**
     * 保留英文半角：为真表示只对中文编码，保留英文字母、数字等英文半角；为假表示对所有字符都编码。默认为假。
     * @param content
     * @return
     */
    public static String unicodeEncode(String content) {
        return unicodeEncode(content, false);
    }

    /**
     *  unicode编码
     * @param content 文本内容
     * @param retainLetter 是否保留英文半角：为true表示只对中文编码，保留英文字母、数字等英文半角；
     *                     为false表示对所有字符都编码。默认为false。
     */
    public static String unicodeEncode(String content, boolean retainLetter) {
        if (content == null) return "";
        if (!retainLetter) {
            StringBuffer out = new StringBuffer("");
            try {
                byte[] bytes = content.getBytes("unicode");
                for (int i = 0; i < bytes.length - 1; i += 2) {
                    out.append("\\u");
                    String str = Integer.toHexString(bytes[i + 1] & 0xff);
                    for (int j = str.length(); j < 2; j++) {
                        out.append("0");
                    }
                    String str1 = Integer.toHexString(bytes[i] & 0xff);
                    out.append(str1);
                    out.append(str);
                }
                return out.toString();
            } catch (UnsupportedEncodingException e) {
                return content;
            }
        }
        Pattern pattern = Pattern.compile("[^\\u0000-\\u00ff]{1}");
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            String tmpStr = matcher.group();
            StringBuffer out = new StringBuffer("");
            try {
                byte[] bytes = tmpStr.getBytes("unicode");
                for (int i = 0; i < bytes.length - 1; i += 2) {
                    out.append("\\u");
                    String str = Integer.toHexString(bytes[i + 1] & 0xff);
                    for (int j = str.length(); j < 2; j++) {
                        out.append("0");
                    }
                    String str1 = Integer.toHexString(bytes[i] & 0xff);
                    out.append(str1);
                    out.append(str);
                }
                content = content.replace(tmpStr, out.toString());
            } catch (UnsupportedEncodingException e) {
            }
        }

        return content;
    }

    /**
     * unicode解码
     * @param content 文本内容
     */
    public static String unicodeDecode(String content) {
        if (content == null) return "";
        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
        Matcher matcher = pattern.matcher(content);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            content = content.replace(matcher.group(1), ch + "");
        }
        return content;
    }

    /**
     * 编码转换
     * @param content 文本内容
     * @param beforeEncoding 原文本编码
     * @param afterEncoding 处理后的文本编码
     */
    public static String convert(String content, String beforeEncoding, String afterEncoding) {
        try {
            return new String(content.getBytes(beforeEncoding), afterEncoding);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
}
